package com.soccertgc.core.game
{

	import com.soccertgc.utils.ClassUtils;
	
	public class GamePhase
	{
			
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------              
		
		public static const SUBSTITUTE:GamePhase				= new GamePhase(1, "SUBSTITUTE", 			false, 	true);
		public static const RESOLVE_SUBSTITUTE:GamePhase        = new GamePhase(2, "RESOLVE_SUBSTITUTE", 	true, 	false);
		public static const DISCARD:GamePhase                	= new GamePhase(3, "DISCARD", 				false, 	true);
		public static const RESOLVE_DISCARD:GamePhase        	= new GamePhase(4, "RESOLVE_DISCARD", 		true, 	false);
		public static const PLAY:GamePhase                		= new GamePhase(5, "PLAY", 					false, 	true);
		public static const RESOLVE_PLAY:GamePhase              = new GamePhase(6, "RESOLVE_PLAY", 			true, 	false);
		public static const RESYNC:GamePhase                	= new GamePhase(8, "RESYNC", 				false, 	false);
		
		/*
		1 = sendSubs
		2 = solveSubs [polling]
		3 = sendDiscard
		4 = solveDiscard [polling]
		5 = sendPlay
		6 = solvePlay [polling]
		7 = getGameInfo [NO-WRAP]
		8 = getGameInfo 
		9 = getRoundLog [NO-WRAP]
		10 = getRoundLog 
		*/
		
		// -------------------------------------------------------------------------------
		// STATIC
		// -------------------------------------------------------------------------------
		
		private static var _initialized:Boolean = false;
		private static var _list:Vector.<GamePhase>;
		
		// Fake static constructor
		{
			// Fill the internal list
			_list = new Vector.<GamePhase>();
			_list.push(GamePhase.SUBSTITUTE);
			_list.push(GamePhase.RESOLVE_SUBSTITUTE);
			_list.push(GamePhase.DISCARD);
			_list.push(GamePhase.RESOLVE_DISCARD);
			_list.push(GamePhase.PLAY);
			_list.push(GamePhase.RESOLVE_PLAY);
			_list.push(GamePhase.RESYNC);
			// Init!
			_initialized = true;
		}
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		private var _id:uint;
		private var _name:String;
		private var _polling:Boolean;	// Polling flag, if true the client repeat the request until a valid result is returned
		private var _active:Boolean;	// Active flag, if false the engine automatically sends the request when the phase starts
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTORS
		// -------------------------------------------------------------------------------
		
		public function GamePhase(id:uint, name:String, polling:Boolean, active:Boolean)
		{
			// Safe unique instance lock
			if (_initialized) throw new Error("GamePhase enum already created!");
			// Init
			_id    	 = id;
			_name  	 = name;
			_polling = polling;
			_active  = active;
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------              

		public function get id():uint
		{
			return _id;
		}
		
		public function get name():String
		{
			return _name;
		}
		
		public function get polling():Boolean
		{
			return _polling;
		}
		
		public function get active():Boolean
		{
			return _active;
		}
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
		
		public function toString():String
		{
			return ClassUtils.getName(this) + "." + _name;
		}
		
		// -------------------------------------------------------------------------------
		// STATIC METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * Returns the list of the names of the game sides
		 * @return List of the names of the game sides
		 */
		public static function names():Array
		{
			var list:Array  = new Array;
			// Loop over values list
			for (var i:int=0; i<_list.length; i++)
			{
				list.push(_list[i].name);
			}
			return list;
		}
		
		/**
		 * 
		 * @return 
		 */
		public static function list():Array
		{
			var list:Array = new Array;
			// Loop over values list
			for (var i:int=0; i<_list.length; i++)
			{
				list.push(_list[i]);
			}
			return list;
		}
		
		/**
		 * Search a GamePhase by given id 
		 * @param id Id of the log target to find
		 * @return GamePhase constant for the given id
		 * for the given id has been found
		 */             
		public static function getById(id:uint):GamePhase
		{
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].id == id) return _list[i];
			}
			throw new Error("GamePhase for id '" + id + "' unknown!");
		}
		
		/**
		 * Search a GamePhase by given name 
		 * @param name Name of the log target to find
		 * @return GamePhase constant for the given name
		 * for the given name has been found
		 */             
		public static function getByName(name:String):GamePhase
		{
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].name == name) return _list[i];
			}
			throw new Error("GamePhase for name '" + name + "' unknown!");
		}
		
		/**
		 * Get the GamePhase linked to the current GameStatus 
		 * @param name Name of the log target to find
		 * @return GamePhase constant for the given id
		 * for the given name has been found
		 */  
		public static function getByGameStatus(status:GameStatus):GamePhase
		{
			var phase:GamePhase = null; 
			// Check status
			switch(status)
			{
				case GameStatus.SUBSTITUTION:			phase = GamePhase.SUBSTITUTE; 			break;
				case GameStatus.RESOLVE_SUBSTITUTION:	phase = GamePhase.RESOLVE_SUBSTITUTE; 	break;
				case GameStatus.DISCARD:				phase = GamePhase.DISCARD; 				break;
				case GameStatus.RESOLVE_DISCARD:		phase = GamePhase.RESOLVE_DISCARD; 		break;
				case GameStatus.PLAY:					phase = GamePhase.PLAY; 				break;
				case GameStatus.RESOLVE_PLAY: 			phase = GamePhase.RESOLVE_PLAY; 		break;
				case GameStatus.RESYNC:					phase = GamePhase.RESYNC; 				break;
			}
			return phase;
		}
		
	}

}